package com.etl.es.charts.base;

import com.eksframework.commons.core.base.EksCheck;
import com.eksframework.commons.core.base.EksDate;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.*;

/**
 * 图表接口
 */
public interface ISearchChart {

    /**
     * 查询条件组装
     *
     * @param param 图表参数
     * @return QueryBuilder
     */
    default QueryBuilder queryBuilder(ChartParam param) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 订单参数
        if (param instanceof ChartParamOrder) {
            param.setDatetimeField(ChartParam.DATETIME_FIELD_ORDER);
            ChartParamOrder paramOrder = (ChartParamOrder) param;
            // 组装查询条件：年月日时
            this.boolQueryMust(boolQuery, "orderYear", paramOrder.getOrderYear());
            this.boolQueryMust(boolQuery, "orderMonth", paramOrder.getOrderMonth());
            this.boolQueryMust(boolQuery, "orderDay", paramOrder.getOrderDay());
            this.boolQueryMust(boolQuery, "orderHour", paramOrder.getOrderHour());
        }
        // 商品参数
        if (param instanceof ChartParamGoods) {
            param.setDatetimeField(ChartParam.DATETIME_FIELD_GOODS);
            ChartParamGoods paramGoods = (ChartParamGoods) param;
            // 组装查询条件：商品类型
            this.boolQueryMust(boolQuery, "goodsTypeName", paramGoods.getGoodsTypeName());
        }
        // 影票参数
        if (param instanceof ChartParamFilmTicket) {
            param.setDatetimeField(ChartParam.DATETIME_FIELD_FILM_TICKET);
            ChartParamFilmTicket paramFilmTicket = (ChartParamFilmTicket) param;
            // 组装查询条件：影片
            this.boolQueryMust(boolQuery, "filmName", paramFilmTicket.getFilmName());
            // 组装查询条件：年月日时
            this.boolQueryMust(boolQuery, "sessionYear", paramFilmTicket.getSessionYear());
            this.boolQueryMust(boolQuery, "sessionMonth", paramFilmTicket.getSessionMonth());
            this.boolQueryMust(boolQuery, "sessionDay", paramFilmTicket.getSessionDay());
            this.boolQueryMust(boolQuery, "sessionHour", paramFilmTicket.getSessionHour());
        }
        // 组装查询条件：时间范围
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(param.getDatetimeField())
                .gte(EksDate.of(param.getDatetimeStart()).toString(EksDate.PATTERN_STRICT_DATE_OPTIONAL_TIME))
                .lte(EksDate.of(param.getDatetimeEnd()).toString(EksDate.PATTERN_STRICT_DATE_OPTIONAL_TIME))
                .format("strict_date_optional_time");
        boolQuery.must(rangeQuery);
        // 组装查询条件：院线
        this.boolQueryMust(boolQuery, "tenantCode", param.getTenantCode());
        this.boolQueryMust(boolQuery, "tenantName", param.getTenantName());
        // 组装查询条件：影院
        this.boolQueryMust(boolQuery, "cinemaCode", param.getCinemaCode());
        this.boolQueryMust(boolQuery, "cinemaName", param.getCinemaName());
        // 组装查询条件：渠道类型
        this.boolQueryMust(boolQuery, "channelTypeCode", param.getChannelTypeCode());
        this.boolQueryMust(boolQuery, "channelTypeName", param.getChannelTypeName());
        // 组装查询条件：渠道
        this.boolQueryMust(boolQuery, "channelCode", param.getChannelCode());
        this.boolQueryMust(boolQuery, "channelName", param.getChannelName());
        return boolQuery;
    }

    /**
     * 组装查询条件
     *
     * @param boolQuery  BoolQueryBuilder
     * @param fieldName  字段名称
     * @param fieldValue 字段值
     */
    default void boolQueryMust(BoolQueryBuilder boolQuery, String fieldName, String fieldValue) {
        if (EksCheck.isBlank(fieldValue)) {
            return;
        }
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(
                fieldName, StringUtils.trimToEmpty(fieldValue));
        boolQuery.must(matchQueryBuilder);
    }

    /**
     * 图表查询接口
     *
     * @param param 图表参数
     * @return ChartsResult图表结果
     */
    ChartResult search(ChartParam param);
}
